package com.dgut.lab.service;

import com.dgut.lab.entity.Answer;
import com.dgut.lab.entity.User;
import com.dgut.lab.mapper.AnswerRepository;
import com.dgut.lab.util.CommonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

@Service
public class AnswerService{
    @Resource
    private AnswerRepository answerRepository;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private UserService userService;

    @Transactional
    public Answer addAnswer(Answer answer) {
        Answer insert = answerRepository.insert(answer);
        User user = new User();
        user.setUsername(answer.getUsername());
        user.setLastCommitTime(new Date());
        boolean b = userService.modifyUserStatus(user);
        if(b)
            return insert;
        return null;
    }

    public Answer queryById(Answer answer) {
        return answerRepository.findById(answer.getAnswerId()).get();
    }

    public List<Answer> queryByVersion(Answer answer) {
        return answerRepository.findByVersion(answer.getVersion());
    }

    public List<Answer> queryByUsername(String username) {
        return answerRepository.findByUsername(username);
    }

    public Answer queryByUsernameLasted(String username){
        Query query = Query.query(Criteria.where("username").is(username)).with(Sort.by(
                Sort.Order.desc("date"),Sort.Order.desc("id")
                ));
        Answer one = mongoTemplate.findOne(query, Answer.class);
        return one;
    }

    public Page<Answer> queryAllByPage(int page, int rows) {
        PageRequest pageRequest = PageRequest.of(page-1,rows);
        return answerRepository.findAll(pageRequest);
    }

//    地址、体温、日期
    public List<Answer> queryUserByCondition(String address,String lowTemperature,String highTemperature,Date startDate,Date endDate){
        Criteria where = new Criteria();
        Pattern pattern = Pattern.compile(".*?" + CommonUtil.escapeExprSpecialWord(address) + ".*");

        if(address!=null){
            where.and("answers.1").regex(pattern);
        }

        if(lowTemperature!=null&&highTemperature!=null){
            where.andOperator(
                    Criteria.where("answers.5").gte(lowTemperature),
                    Criteria.where("answers.5").lte(highTemperature)
            );
        }
        else if(lowTemperature!=null)
            where.and("answers.5").gte(lowTemperature);
        else if(highTemperature!=null)
            where.and("answers.5").lte(highTemperature);
        if(startDate!=null && endDate !=null)
        {
            where.andOperator(
              Criteria.where("date").gte(startDate),
              Criteria.where("date").lte(endDate)
            );
        }
        else if(startDate!=null)
            where.and("date").gte(startDate);
        else if(endDate!=null)
            where.and("date").lte(endDate);
        Query query = new Query(where);
        query.fields().include("username");
//        PageRequest pageRequest = PageRequest.of(page-1,rows);
        query.with(Sort.by(Sort.Order.asc("username")));
        return mongoTemplate.find(query,Answer.class);
    }

    /**
     * 1.地址、2.身体状况、3是否到达重点地区、4.是否为重点人群、
     * 5.体温（minTemperature-maxTemperature）
     * 6.曾到达的重点地区
     * 7.打卡时间（minDate,maxDate）
     * 8.学号
     * @param map
     * @return
     */
    public List<Answer> queryAnswerByCondition(Map<String,Object> map) throws ParseException {
        Criteria criteria = new Criteria();
        if(map.get("address")!=null){
            Pattern address = Pattern.compile(".*?" + CommonUtil.escapeExprSpecialWord((String) map.get("address")) + ".*");
            criteria.and("answers.1").regex(address);
        }
        if(map.get("condition")!=null){
            criteria.and("answers.2").is(((String) map.get("condition")));
        }

        if(map.get("isArea")!=null){
            criteria.and("answers.3").is(((String) map.get("isArea")));
        }
        if(map.get("group")!=null) {
            criteria.and("answers.4").is(((String) map.get("group")));
        }
        if((map.get("minTemperature")!=null) && (map.get("maxTemperature")!=null)){

            criteria.andOperator(
                    Criteria.where("answers.5").gte(((String) map.get("minTemperature"))),
                    Criteria.where("answers.5").lte(((String) map.get("maxTemperature")))
            );
        }
        else if(map.get("minTemperature")!=null){

            criteria.and("answers.5").gte((map.get("minTemperature")));
        }
        else if (map.get("maxTemperature")!=null){

            criteria.and("answers.5").lte((map.get("maxTemperature")));
        }
        if(map.get("area")!=null){
            Pattern area = Pattern.compile(".*?" + CommonUtil.escapeExprSpecialWord((String) map.get("area")) + ".*");
            criteria.and("answers.3-2-1").regex(area);
        }
        if(map.get("minDate")!=null && map.get("maxDate") !=null) {
            Date minDate = CommonUtil.StringToDate(((String) map.get("minDate")));
            Date maxDate = CommonUtil.StringToDate(((String) map.get("maxDate")));
            criteria.andOperator(
                    Criteria.where("date").gte(minDate),
                    Criteria.where("date").lte(maxDate)
            );
        }
        else if(map.get("minDate")!=null){
            Date minDate = CommonUtil.StringToDate(((String) map.get("minDate")));
            criteria.and("date").gte(minDate);
        }
        else if(map.get("maxDate")!=null){
            Date maxDate = CommonUtil.StringToDate(((String) map.get("maxDate")));
            criteria.and("date").lte( maxDate);
        }

        if(map.get("username")!=null){
            Pattern username = Pattern.compile(".*?" + CommonUtil.escapeExprSpecialWord((String) map.get("username")) + ".*");
            criteria.and("username").regex(username);
        }

        Query query = new Query().addCriteria(criteria).with(
                Sort.by(Sort.Order.desc("date"),
                        Sort.Order.asc("username"))
        );
        List<Answer> answers = mongoTemplate.find(query, Answer.class);
        return answers;
    }
}
